package acme.bloodtime.dao;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import modelo.ICiudadDAO;
import modelo.ICiudadDO;
import dao.api.DataObject;
import dao.api.FactoryDAO;

/**
 * 
 * @author Eduardo D. Sandoval V.
 * 
 */
public class CiudadDAO extends BloodTimeBaseDAO implements ICiudadDAO {

    public static String TABLE_NAME = "ciudad";

    public CiudadDAO() {
        // empty
    }

    public void createTable() throws SQLException {
        StringBuffer strbuf;

        // ----------------------------------------

        dropTable();

        // ----------------------------------------

        strbuf = new StringBuffer();

        strbuf.append("CREATE TABLE ");
        strbuf.append(getTableName());
        strbuf.append(" (");
        strbuf.append(CiudadDO.ID);
        strbuf.append(" SERIAL PRIMARY KEY, ");
        strbuf.append(CiudadDO.NOMBRE);
        strbuf.append(" VARCHAR(100),    ");
        strbuf.append(CiudadDO.DESCRIPCION);
        strbuf.append(" VARCHAR(100),     ");
        strbuf.append(CiudadDO.IMAGEN);
        strbuf.append(" BYTEA,      ");
        strbuf.append(CiudadDO.PTOS_REQUERIDOS);
        strbuf.append(" INT ");
        strbuf.append(")");

        System.err.println(strbuf.toString());

        connection.createStatement().execute(strbuf.toString());

    }

    // --------------------------------------------------------------------------------

    @Override
    public void insert(DataObject dataObject) throws SQLException {
        checkCache(dataObject, CHECK_INSERT);
        checkClass(dataObject, CiudadDO.class, CHECK_INSERT);

        CiudadDO ciudadDO = (CiudadDO) dataObject;

        ciudadDO.setId(getNextId());

        StringBuffer strbuf = new StringBuffer();

        strbuf.append("INSERT INTO ");
        strbuf.append(getTableName());
        strbuf.append(" VALUES (");
        strbuf.append(ciudadDO.getId());
        strbuf.append(", ");
        strbuf.append(singleQuotes(ciudadDO.getNombre()));
        strbuf.append(", ");
        strbuf.append(singleQuotes(ciudadDO.getDescripcion()));
        strbuf.append(", ");
        strbuf.append("?, ");
        strbuf.append(ciudadDO.getPtosRequeridos());
        strbuf.append(")");

        // ---------------------------------------------------------------
        // The PreparedStatement is used to do the insertion of the image
        // ---------------------------------------------------------------

        PreparedStatement ps = connection.prepareStatement(strbuf.toString());
        ps.setBytes(1, ciudadDO.getImagen());

        ps.executeUpdate();
        ps.close();

        System.err.println(strbuf.toString());

        dtaSession.add(dataObject);
    }

    // --------------------------------------------------------------------------------

    @Override
    public void update(DataObject dataObject) throws SQLException {
        checkCache(dataObject, CHECK_UPDATE);
        checkClass(dataObject, CiudadDO.class, CHECK_UPDATE);

        CiudadDO ciudadDO = (CiudadDO) dataObject;

        StringBuffer strbuf = new StringBuffer();

        strbuf.append("UPDATE ");
        strbuf.append(getTableName());
        strbuf.append(" SET ");

        strbuf.append(CiudadDO.NOMBRE);
        strbuf.append(" = ");
        strbuf.append(singleQuotes(ciudadDO.getNombre()));

        strbuf.append(", ");

        strbuf.append(CiudadDO.DESCRIPCION);
        strbuf.append(" = ");
        strbuf.append(singleQuotes(ciudadDO.getDescripcion()));

        strbuf.append(", ");

        strbuf.append(CiudadDO.IMAGEN);
        strbuf.append(" = ");
        strbuf.append(" ? ");

        strbuf.append(", ");

        strbuf.append(CiudadDO.PTOS_REQUERIDOS);
        strbuf.append(" = ");
        strbuf.append(ciudadDO.getPtosRequeridos());

        strbuf.append(" WHERE ");
        strbuf.append(CiudadDO.ID);
        strbuf.append(" = ");
        strbuf.append(ciudadDO.getId());

        PreparedStatement ps = connection.prepareStatement(strbuf.toString());
        ps.setBytes(1, ciudadDO.getImagen());

        ps.executeUpdate();
        ps.close();

        System.err.println(strbuf.toString());

    }

    // --------------------------------------------------------------------------------

    @Override
    public void delete(DataObject ciudadDO) throws SQLException {
        internalDelete(ciudadDO, CiudadDO.class);
    }

    // --------------------------------------------------------------------------------

    protected CiudadDO resultSetToDO(ResultSet rs) throws SQLException {
        CiudadDO ret = //
        (CiudadDO) dtaSession.getDtaByKey( //
                CiudadDO.class, rs.getInt(CiudadDO.ID));

        if (ret != null) {
            return ret;
        }

        ret = new CiudadDO();

        ret.setId/*     */(rs.getInt(CiudadDO.ID));
        ret.setNombre/*   */(rs.getString(CiudadDO.NOMBRE));
        ret.setDescripcion(rs.getString(CiudadDO.DESCRIPCION));
        ret.setImagen(rs.getBytes(CiudadDO.IMAGEN));
        ret.setPtosRequeridos(rs.getInt(CiudadDO.PTOS_REQUERIDOS));

        return (CiudadDO) dtaSession.add(ret);
    }

    // --------------------------------------------------------------------------------

    public void loadVampiroList(ICiudadDO ciudadDO) throws Exception {
        checkCache(ciudadDO, CHECK_UPDATE);
        checkClass(ciudadDO, CiudadDO.class, CHECK_UPDATE);

        VampiroDAO vampiroDAO = (VampiroDAO) FactoryDAO.getDAO( //
                VampiroDAO.class, connectionBean);

        ciudadDO.setVampiroList(vampiroDAO.listByCiudadId(ciudadDO.getId()));
    }

    // ----------------------------------------------------------------------------------

    public void loadPropiedadVampiroList(ICiudadDO ciudadDO) throws Exception {
        checkCache(ciudadDO, CHECK_UPDATE);
        checkClass(ciudadDO, CiudadDO.class, CHECK_UPDATE);

        PropiedadVampiroDAO propiedadVampiroDAO = (PropiedadVampiroDAO) FactoryDAO.getDAO( //
                PropiedadVampiroDAO.class, connectionBean);

        ciudadDO.setPropiedadVampiroList(propiedadVampiroDAO.listByCiudadId(ciudadDO.getId()));
    }

    // ----------------------------------------------------------------------------------

    public void loadCiudadDistanciaDerList(ICiudadDO ciudadDO) throws Exception {
        checkCache(ciudadDO, CHECK_UPDATE);
        checkClass(ciudadDO, CiudadDO.class, CHECK_UPDATE);

        CiudadDistanciaDAO ciudadDistanciaDAO = (CiudadDistanciaDAO) FactoryDAO.getDAO( //
                CiudadDistanciaDAO.class, connectionBean);

        ciudadDO.setCiudadDistanciaDerList(ciudadDistanciaDAO.listByCiudadIzqId(ciudadDO.getId()));
    }

    // ----------------------------------------------------------------------------------

    public void loadCiudadDistanciaIzqList(ICiudadDO ciudadDO) throws Exception {
        checkCache(ciudadDO, CHECK_UPDATE);
        checkClass(ciudadDO, CiudadDO.class, CHECK_UPDATE);

        CiudadDistanciaDAO ciudadDistanciaDAO = (CiudadDistanciaDAO) FactoryDAO.getDAO( //
                CiudadDistanciaDAO.class, connectionBean);

        ciudadDO.setCiudadDistanciaIzqList(ciudadDistanciaDAO.listByCiudadDerId(ciudadDO.getId()));
    }

    public void loadVisitaList(ICiudadDO ciudadDO) throws Exception {
        checkCache(ciudadDO, CHECK_UPDATE);
        checkClass(ciudadDO, CiudadDO.class, CHECK_UPDATE);

        VisitaDAO visitaDAO = (VisitaDAO) FactoryDAO.getDAO( //
                VisitaDAO.class, connectionBean);

        ciudadDO.setVisitaList(visitaDAO.listByCiudadId(ciudadDO.getId()));
    }

    @Override
    public byte[] loadImageByCiudadId(int ciudadId) throws SQLException {
        StringBuffer strbuf = new StringBuffer();

        strbuf.append("SELECT ");
        strbuf.append(CiudadDO.IMAGEN);
        strbuf.append(" FROM ");
        strbuf.append(getTableName());
        strbuf.append(" WHERE ");
        strbuf.append(CiudadDO.ID);
        strbuf.append(" = ");
        strbuf.append(ciudadId);

        System.err.println(strbuf.toString());

        ResultSet rs = //
        connection.createStatement().executeQuery(strbuf.toString());

        if (rs.next()) {
            return rs.getBytes(CiudadDO.IMAGEN);
        }

        return null;
    }

}
